﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms.Extensions.Appearance;
using System.Windows.Forms.Extensions.Appearance.Interface;
using System.Windows.Forms.Extensions.Appearance.Subcontrols;
using System.Windows.Forms.Extensions.Model;

namespace System.Windows.Forms.Extensions
{
    /// <summary>
    /// ShutterNotifyer control
    /// </summary>
    public partial class ShutterNotifier : Component
    {

        #region Public properties

        /// <summary>
        /// Notifyer's parent control (i.e. the Form)
        /// </summary>
        [Browsable(true)]
        [Description("Notifyer's parent control (i.e. the Form).")]
        public Control ParentControl { get; set; }

        /// <summary>
        /// Notifyer's color scheme
        /// </summary>
        [Browsable(true)]
        [Description("Notifyer's color scheme.")]
        public Constants.Themes Theme { get; set; }

        /// <summary>
        /// Notifyer's icon on the left
        /// </summary>
        [Browsable(true)]
        [Description("Notifyer's icon on the left.")]
        public Constants.Icons Icon { get; set; }

        /// <summary>
        /// Notifyer's in and out-animation
        /// </summary>
        [Browsable(true)]
        [Description("Notifyer's in and out-animation.")]
        public Constants.Animations Animation { get; set; }

        /// <summary>
        /// How to hide the notifyer? Is the whole area clickable or just a button?
        /// </summary>
        [Browsable(true)]
        [Description("How to hide the notifyer? Is the whole area clickable or just a button?")]
        public Constants.ClickableControls ConcealmentMethod { get; set; }
    
        /// <summary>
        /// Is the item in the warning list clickable?
        /// </summary>
        [Browsable(true)]
        [Description("Is an item in the warning list clickable?")]
        public bool IsWarningListItemClickable { get; set; }

        #endregion

        #region Private declarations

        /// <summary>
        /// The animated notifyer area
        /// </summary>
        private INotifierPanel _notifierArea;
        
        #endregion

        #region Public actions

        #region Overrides

        /// <summary>
        /// Simple text in the notifyer
        /// </summary>
        /// <param name="text">Text</param>
        public void In(string text)
        {
            In(new NotifierMessage(text, "", new List<WarningItem>()));
        }

        /// <summary>
        /// Bolded and simple texts in the notifyer
        /// </summary>
        /// <param name="text">Text (bold)</param>
        /// <param name="textAdditional">Additional normal text</param>
        public void In(string text, string textAdditional)
        {
            In(new NotifierMessage(text, textAdditional, new List<WarningItem>()));
        }

        /// <summary>
        /// Texts and warning list
        /// </summary>
        /// <param name="text">Text (bold)</param>
        /// <param name="textAdditional">Additional text</param>
        /// <param name="warningItems">List of warning items</param>
        public void In(string text, string textAdditional, IEnumerable<string> warningItems)
        {
            In(new NotifierMessage(text,
                                   textAdditional,
                                   warningItems.Select(x => new WarningItem(x)).ToList()));
        }

        /// <summary>
        /// Text and warning list
        /// </summary>
        /// <param name="text">Text (bold)</param>
        /// <param name="warningItems">List of warning items</param>
        public void In(string text, IEnumerable<string> warningItems)
        {
            In(new NotifierMessage(text,
                                   "",
                                   warningItems.Select(x => new WarningItem(x)).ToList()));
        }

        /// <summary>
        /// Texts and warning list
        /// </summary>
        /// <param name="text">Text (bold)</param>
        /// <param name="textAdditional">Additional text</param>
        /// <param name="warningItems">List of warning items</param>
        public void In(string text, string textAdditional, IEnumerable<WarningItem> warningItems)
        {
            In(new NotifierMessage(text,
                                   textAdditional,
                                   warningItems));
        }

        /// <summary>
        /// Text and warning list
        /// </summary>
        /// <param name="text">Text (bold)</param>
        /// <param name="warningItems">List of warning items</param>
        public void In(string text, IEnumerable<WarningItem> warningItems)
        {
            In(new NotifierMessage(text,
                                   "",
                                   warningItems));
        }

        #endregion

        /// <summary>
        /// Show the notifyer message with this message
        /// </summary>
        /// <param name="message">The message</param>
        public void In(NotifierMessage message)
        {
            // Create area if not exist
            CreateNotifyerArea();

            // Set area properties
            _notifierArea.SetTheme(EnumMapper.GetThemeByName(Theme));

            _notifierArea.SetIcon(EnumMapper.GetIconByName(Icon));
            
            _notifierArea.SetText(message);

            AnimateIn(EnumMapper.GetAnimationByName(Animation));

        }

        /// <summary>
        /// Hide the notifyer with animation
        /// </summary>
        public void Out()
        {
            AnimateOut(EnumMapper.GetAnimationByName(Animation));
        }

        #endregion

        #region Private methods

        #region In

        private void AnimateIn(IAnimation animation)
        {               
            animation.In(EnumMapper.GetThemeByName(Theme), _notifierArea);
        }

        #endregion

        #region Out

        private void AnimateOut(IAnimation animation)
        {
            animation.Out(EnumMapper.GetThemeByName(Theme), _notifierArea);
        }

        #endregion

        #region Factory

        private void CreateNotifyerArea()
        {
            // Guard
            if (ParentControl == null) throw new ArgumentNullException("ParentControl");
            
            // Create base notify control
            if (_notifierArea == null)
            {
                _notifierArea = new NotifierPanel {Width = ParentControl.Width, Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top, Visible = false};

                // Add to the parent
                ParentControl.Controls.Add(_notifierArea as Control); // ...eh

                // Events
                _notifierArea.HideNotifierPanelEvent += (o, k) => Out();

                // Clicking on the parent control should hide the notifier
                ParentControl.Click += (o, k) => Out();

            }

            _notifierArea.Visible = false;

            _notifierArea.SetClickableArea(ConcealmentMethod);

            _notifierArea.BringToFront();
            
        }

        #endregion

        #endregion

        #region Constructors

        public ShutterNotifier()
        {
            InitializeComponent();
        }

        public ShutterNotifier(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        #endregion

    }
}
